package com.atguigu.product.service.impl;

import com.alibaba.druid.sql.ast.statement.SQLForeignKeyImpl;
import com.atguigu.clients.CategoryClient;
import com.atguigu.clients.SearchClient;
import com.atguigu.param.*;
import com.atguigu.pojo.Picture;
import com.atguigu.pojo.Product;
import com.atguigu.product.mapper.PictureMapper;
import com.atguigu.product.mapper.ProductMapper;
import com.atguigu.product.service.ProductService;
import com.atguigu.to.OrderToProduct;
import com.atguigu.utils.R;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import com.atguigu.pojo.Category;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.util.StringUtils;

import javax.swing.*;
import javax.swing.text.ParagraphView;
import java.util.*;
import java.util.stream.Collectors;

/**
 * ClassName:ProductServiceImpl
 * Package:com.atguigu.product.service.impl
 * Description:
 *
 * @Author 应永豪
 * @Create 2024/4/21 21:10
 * @Version 1.0
 */
@Service
@Slf4j
public class ProductServiceImpl extends ServiceImpl<ProductMapper,Product> implements ProductService {

    //引入feign客户端需要在启动类里添加配置注解
    @Autowired
    private CategoryClient categoryClient;
    @Autowired
    private ProductMapper productMapper;

    @Autowired
    private PictureMapper pictureMapper;

    @Autowired
    private SearchClient searchClient;
    @Cacheable(value = "list.product",key = "#categoryName",cacheManager = "cacheManagerDay")
    //value表示的是缓存分区名，便于后面批量删除
    //key表示的是缓存的key，根据key取值
    //cacheManager用来设置缓存有效期，其实配置文件里有配置的，这里不特殊标识的话，默认缓存一小时
    @Override
    public R promo(String categoryName) {
//        1.根据类别名称调用feign客户端访问类别服务获取类别的数据
//        2.如果成功，继续根据类别id查询商品数据（热门，按照销量排序，7条）
//        3.封装返回结果
        R r = categoryClient.byname(categoryName);
        if (r.getCode().equals(R.FAIL_CODE)) {
            log.info("ProductServiceImpl.promo业务结束，结果为：{}", "类别查询失败");
            return r;
        }
//类别服务中的返回数据是Category，调用Feign后会被转换为json，再到调用方的时候就变成了LinkedHashMap
//        Category category = (Category) r.getData();所以不能这么强转
        LinkedHashMap<String, Object> map = (LinkedHashMap<String, Object>) r.getData();
        Integer categoryId = (Integer) map.get("category_id");


        QueryWrapper<Product> productQueryWrapper = new QueryWrapper<>();
        productQueryWrapper.eq("category_id", categoryId).orderByDesc("product_sales");


        IPage<Product> page = new Page<>(1, 7);
        //返回的是包装数据，内部有对应的商品集合，也有分页的参数，例如：总条数，总页数等
        page = productMapper.selectPage(page, productQueryWrapper);

        List<Product> productList = page.getRecords();
//        Long total = page.getTotal();
        log.info("ProductServiceImpl.promo业务结束，结果为：{}", productList);

        return R.ok("数据查询成功", productList);


    }

    @Override
    @Cacheable(value = "list.product" ,key = "#param.categoryName")
    public R hots(ProductHotParam param) {
        R r = categoryClient.hots(param);
        if (r.getCode().equals(R.FAIL_CODE)) {
            log.info("ProductServiceImpl.hots业务结束，结果为：{}", r.getMsg());
            return r;
        }

        List<Object> ids = (List<Object>) r.getData();

        QueryWrapper<Product> productQueryWrapper = new QueryWrapper<>();
        productQueryWrapper.in("category_id", ids).orderByDesc("product_sales");

        IPage<Product>  page =  new Page<>(1, 7);

        page = productMapper.selectPage(page, productQueryWrapper);

        List<Product> records = page.getRecords();

        R ok = R.ok("多类别热门商品查询成功", records);

        log.info("ProductServiceImpl.hots业务结束，结果为：{}", ok);
        return ok;


    }

    @Override
    public R clist() {
        R r = categoryClient.list();
        log.info("ProductServiceImpl.clist业务结束，结果为：{}", r);
        return r;
    }

    @Override
    @Cacheable(value = "list.product" ,key = "#param.categoryID+'-'+#param.currentPage+'-'+#param.pageSize")
    public R byCategory(ProductIdsParam param) {
        List<Integer> categoryID = param.getCategoryID();
        QueryWrapper<Product> productQueryWrapper = new QueryWrapper<>();
        if (!categoryID.isEmpty()){
            productQueryWrapper.in("category_id",categoryID);
        }

        IPage<Product> page = new Page<>(param.getCurrentPage(),param.getPageSize());
        page = productMapper.selectPage(page,productQueryWrapper);
        R ok = R.ok("查询成功", page.getRecords(), page.getTotal());
        log.info("ProductServiceImpl.clist业务结束，结果为：{}",ok);
        return ok;
    }

    @Override
    @Cacheable(value ="product" ,key = "#productID")
    public R detail(Integer productID) {
        Product product = productMapper.selectById(productID);
        R ok = R.ok(product);
        log.info("ProductServiceImpl.clist业务结束，结果为：{}",ok);
        return ok;
    }

    @Override
    @Cacheable(value = "picture" ,key = "#productID")
    public R pictures(Integer productID) {
        QueryWrapper<Picture> pictureQueryWrapper = new QueryWrapper<>();
        pictureQueryWrapper.eq("product_id",productID);

        List<Picture> pictures = pictureMapper.selectList(pictureQueryWrapper);

        R ok = R.ok(pictures);
        log.info("ProductServiceImpl.pictures业务结束，结果为：{}",ok);
        return ok;

    }

    @Override
    @Cacheable(value = "list.category",key = "#root.methodName",cacheManager = "cacheManagerDay")
    public List<Product> allList() {
        List<Product> productList = productMapper.selectList(null);
        log.info("ProductServiceImpl.allList业务结束，结果为：{}",productList.size());
        return productList;
    }


    @Override
    public R search(ProductSearchParam param) {
        R r = searchClient.search(param);
        log.info("ProductServiceImpl.search业务结束，结果为：{}",r);
        return r;
    }

    @Override
    @Cacheable(value = "list.product",key = "#productIds")
    public R ids(List<Integer> productIds) {
        QueryWrapper<Product> productQueryWrapper = new QueryWrapper<>();
        productQueryWrapper.in("product_id",productIds);

        List<Product> productList = productMapper.selectList(productQueryWrapper);

        R r = R.ok("类别信息查询成功", productList);
        log.info("ProductServiceImpl.ids业务结束，结果为：{}",r);
        return r;


    }

    @Override
    public List<Product> cartList(List<Integer> productIds) {
        QueryWrapper<Product> productQueryWrapper = new QueryWrapper<>();
        productQueryWrapper.in("product_id",productIds);
        List<Product> productList = productMapper.selectList(productQueryWrapper);
        log.info("ProductServiceImpl.ids业务结束，结果为：{}",productList);
        return productList;
    }

    @Override
    public void subNumber(List<OrderToProduct> orderToProductList) {
        Map<Integer, OrderToProduct> map = orderToProductList.stream().collect(Collectors.toMap(OrderToProduct::getProductId, v -> v));

        Set<Integer> productIds = map.keySet();
        List<Product> productList = productMapper.selectBatchIds(productIds);

        for (Product product: productList){
            Integer num = map.get(product.getProductId()).getNum();
            product.setProductNum(product.getProductNum()-num);
            product.setProductSales(product.getProductSales()+num);
        }

        this.updateBatchById(productList);

        log.info("ProductServiceImpl.cartList业务结束，结果为：{}","库存和销售量的修改完毕");
    }

    @Override
    public Long adminCount(Integer categoryId) {
        QueryWrapper<Product> productQueryWrapper = new QueryWrapper<>();
        productQueryWrapper.eq("category_id",categoryId);
        Long count = baseMapper.selectCount(productQueryWrapper);
        log.info("ProductServiceImpl.adminCount业务结束，结果为：{}",count);
        return count;
    }

    @Override
    @CacheEvict(value = "list.product",allEntries = true )
    public R adminSave(ProductSaveParam param) {
        Product product = new Product();
        BeanUtils.copyProperties(param,product);

        int rows = productMapper.insert(product);
        log.info("ProductServiceImpl.adminSave业务结束，结果为：{}",rows);

        String pictures = param.getPictures();

        if (!StringUtils.isEmpty(pictures)){
//            截取特殊符号时，需要加\\或者[]，例如+,$,*,|,?
            String[] urls = pictures.split("\\+");


            for (String url : urls){
                Picture picture = new Picture();
                picture.setProductId(product.getProductId());
                picture.setProductPicture(url);
                pictureMapper.insert(picture);
            }

        }

        searchClient.saveOrUpdate(product);
        return R.ok("商品数据添加成功");


    }
}
